﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json.Linq;
using NP.BPMReportPlatform.BPMPlatform;
using NP.BPMReportPlatform.CG;
using NP.BPMReportPlatform.CG.Dto;
using NP.BPMReportPlatform.DBHelper;
using NP.BPMReportPlatform.Entities.BPM_Business;
using NP.BPMReportPlatform.Entities.BPM_Engine;
using NP.BPMReportPlatform.Entities.BPM_Platform;
using NP.BPMReportPlatform.Utils;
using NP.Enterprise.Utils.Http;
using SqlSugar;
using Volo.Abp.Application.Dtos;

namespace NP.BPMReportPlatform.FrameOrder
{
    public class CGOrderService : BPMReportPlatformAppService, ICGOrderService
    {
        private readonly SqlSugarClient _db;
        private readonly SqlSugarClient _dbPlatform;
        private readonly SqlSugarClient _dbEngine;
        private readonly IBPMUtilsAppService _bPMUtilsApp;
        private readonly IBPMPlatformAppService _iBPMPlatformApp;
        private readonly INPRestHttpHelper _nPRestHttp;

        public CGOrderService(ISqlSugarAppService sqlSugarAppService, IBPMUtilsAppService bPMUtilsApp
            , IBPMPlatformAppService iBPMPlatformApp, INPRestHttpHelper nPRestHttp, IConfiguration configuration)
        {
            _db = sqlSugarAppService.GetBusinessInstance();
            _dbPlatform = sqlSugarAppService.GetPlatformInstance();
            _dbEngine = sqlSugarAppService.GetEngineInstance();
            _bPMUtilsApp = bPMUtilsApp;
            _iBPMPlatformApp = iBPMPlatformApp;
            _nPRestHttp = nPRestHttp;
        }

        #region 新90单TU
        public async Task<PagedResultDto<GetNew90Output>> GetAllAsync(New90Input input)
        {
            RefAsync<int> totalCount = 0;
            //业务需求，以下都属于处理中
            if (!input.OrderStatus.IsNullOrEmpty() && SqlFunc.ContainsArray<string>(input.OrderStatus.ToArray(), "处理中"))
            {
                input.OrderStatus.Add("退回发起人（直接提交退回人）");
                input.OrderStatus.Add("退回发起人（逐级提交）");
                input.OrderStatus.Add("发起人撤回");
            }
            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToPageListAsync(input.PageIndex, input.PageSize, totalCount);
            var userId = await _iBPMPlatformApp.GetUserAsync(CurrentUser.UserName);

            listViewDto.ForEach(x => {
                x.Url = _bPMUtilsApp.GetProcessUrl(x.InstanceNumber, userId);
                x.OrderStatus = GetInstanceType(x.InstanceNumber);
            });
            //返回结果
            return new PagedResultDto<GetNew90Output>()
            {
                TotalCount = totalCount,
                Items = listViewDto
            };
        }

        public async Task<List<GetNew90Output>> ExportAsync(New90Input input)
        {
            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToListAsync();
            return listViewDto;
        }

        /// <summary>
        /// 获取Queryable(报表展现)
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        private ISugarQueryable<GetNew90Output> GetQueryable(New90Input input)
        {

            var listQueryable = _db.Queryable<New90Header, New90Detail, BusinessProcessesNew>(
                    (x, m, bu) => new JoinQueryInfos(JoinType.Left, x.InstanceNumber == m.InstanceNumber, JoinType.Left, x.InstanceNumber == bu.InstanceId))
                .WhereIF(!string.IsNullOrWhiteSpace(input.InstanceNumber), (x, m) => x.InstanceNumber.Contains(input.InstanceNumber))
                .WhereIF(!input.OrderStatus.IsNullOrEmpty(), (x, m, bu) => SqlFunc.ContainsArray<string>(input.OrderStatus.ToArray(), bu.ProcessStatusName))
                .WhereIF(!string.IsNullOrWhiteSpace(input.AddUserName), (x, m, bu) => bu.StartUserName.Equals(input.AddUserName))
                .WhereIF(input.StartCreationTime != null && input.EndCreationTime != null, x => x.AddTime >= input.StartCreationTime && x.AddTime.AddDays(-1) <= input.EndCreationTime)
                .Select((x, m, bu) =>
                    new GetNew90Output()
                    {
                        InstanceNumber = x.InstanceNumber,
                        CreateTime = x.AddTime,
                        AddUserName = bu.StartUserName,
                        Route=x.Route,
                        RouteName=x.RouteName,
                        CostCenterCode=x.CostCenterCode,
                        CostCenterName=x.CostCenterName,
                        DeliveryAddress=x.DeliveryAddress,
                        DeliveryAddressStr=x.DeliveryAddressStr,
                        Contact=x.Contact,
                        ContactDetails=x.ContactDetails,
                        Factory=x.Factory,
                        FactoryName=x.FactoryName,
                        StockLocation=x.StockLocation,
                        StockLocationName=x.StockLocationName,
                        Area=x.Area,
                        Title=x.Title,
                        Content=x.Content,
                        CCUsersName=x.CCUsersName,
                        NinetyNo=x.NinetyNo,
                        ApplicationReason=x.ApplicationReason,
                        Remark=x.Remark,
                        ShippingEstimate=x.ShippingEstimate,
                        Scenes=m.Scenes,
                        SceneDescription=m.SceneDescription,
                        MaterialCode=m.MaterialCode,
                        Number=m.Number,
                        Weight=m.Weight
                    }).MergeTable().Distinct().OrderBy(ins => ins.InstanceNumber, OrderByType.Desc);
            return listQueryable;
        }
        #endregion

        #region SRM订单加急付款申请表
        public async Task<PagedResultDto<GetSRMDDJJFKSQBOutput>> GetAllAsync(SRMDDJJFKSQBInput input)
        {
            //业务需求，以下都属于处理中
            if (!input.OrderStatus.IsNullOrEmpty() && SqlFunc.ContainsArray<string>(input.OrderStatus.ToArray(), "处理中"))
            {
                input.OrderStatus.Add("退回发起人（直接提交退回人）");
                input.OrderStatus.Add("退回发起人（逐级提交）");
                input.OrderStatus.Add("发起人撤回");
            }
            RefAsync<int> totalCount = 0;

            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToPageListAsync(input.PageIndex, input.PageSize, totalCount);
            var userId = await _iBPMPlatformApp.GetUserAsync(CurrentUser.UserName);

            listViewDto.ForEach(x => {
                x.Url = _bPMUtilsApp.GetProcessUrl(x.InstanceNumber, userId);
                x.OrderStatus = GetInstanceType(x.InstanceNumber);
            });
            //返回结果
            return new PagedResultDto<GetSRMDDJJFKSQBOutput>()
            {
                TotalCount = totalCount,
                Items = listViewDto
            };
        }

        public async Task<List<GetSRMDDJJFKSQBOutput>> ExportAsync(SRMDDJJFKSQBInput input)
        {
            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToListAsync();
            return listViewDto;
        }

        /// <summary>
        /// 获取Queryable(报表展现)
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        private ISugarQueryable<GetSRMDDJJFKSQBOutput> GetQueryable(SRMDDJJFKSQBInput input)
        {

            var listQueryable = _db.Queryable<SRMDDJJFKSQBHeader, SRMDDJJFKSQBDetail, BusinessProcessesNew>(
                    (x, m, bu) => new JoinQueryInfos(JoinType.Left, x.InstanceNumber == m.InstanceNumber, JoinType.Left, x.InstanceNumber == bu.InstanceId))
                .WhereIF(!string.IsNullOrWhiteSpace(input.InstanceNumber), (x, m) => x.InstanceNumber.Contains(input.InstanceNumber))
                 .WhereIF(!input.OrderStatus.IsNullOrEmpty(), (x, m, bu) => SqlFunc.ContainsArray<string>(input.OrderStatus.ToArray(), bu.ProcessStatusName))
                .WhereIF(!string.IsNullOrWhiteSpace(input.AddUserName), (x, m, bu) => bu.StartUserName.Equals(input.AddUserName))
                .WhereIF(input.StartCreationTime != null && input.EndCreationTime != null, x => x.AddTime >= input.StartCreationTime && x.AddTime.AddDays(-1) <= input.EndCreationTime)
                .Select((x, m, bu) =>
                    new GetSRMDDJJFKSQBOutput()
                    {
                        InstanceNumber = x.InstanceNumber,
                        CreateTime = x.AddTime,
                        AddUserName = bu.StartUserName,
                        FeeType = x.FeeType,
                        PaymentType = x.PaymentType,
                        CompanyCode = x.CompanyCode,
                        CompanyName = x.CompanyName,
                        CapitalCost = x.CapitalCost,
                        CompanyRequire = x.CompanyRequire,
                        OtherReason = x.OtherReason,
                        CapitalCostAssessment = x.CapitalCostAssessment,
                        Content = x.Content,
                        SupplierName = m.SupplierName,
                        SupplierCode = m.SupplierCode,
                        PurchaseOrderNumber = m.PurchaseOrderNumber,
                        InvoiceNumber=m.InvoiceNumber,
                        InvoiceDate = m.InvoiceDate,
                        Amount=m.Amount,
                        ExpectedPaymentDate=m.ExpectedPaymentDate,
                        IsBookKeeping=m.IsBookKeeping,
                        SupplierBillingPeriod= m.SupplierBillingPeriod,
                        ScheduleInvoicePaymentTime=m.ScheduleInvoicePaymentTime
                    }).MergeTable().Distinct().OrderBy(ins => ins.InstanceNumber, OrderByType.Desc);
            return listQueryable;
        }
        #endregion

        #region 立邦包装外观与色彩打样申请 
        public async Task<PagedResultDto<GetBZWGYSDYOutput>> GetAllAsync(BZWGYSDYInput input)
        {
            RefAsync<int> totalCount = 0;
            //业务需求，以下都属于处理中
            if (!input.OrderStatus.IsNullOrEmpty() && SqlFunc.ContainsArray<string>(input.OrderStatus.ToArray(), "处理中"))
            {
                input.OrderStatus.Add("退回发起人（直接提交退回人）");
                input.OrderStatus.Add("退回发起人（逐级提交）");
                input.OrderStatus.Add("发起人撤回");
            }
            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToPageListAsync(input.PageIndex, input.PageSize, totalCount);
            var userId = await _iBPMPlatformApp.GetUserAsync(CurrentUser.UserName);

            listViewDto.ForEach(x => {
                x.Url = _bPMUtilsApp.GetProcessUrl(x.InstanceNumber, userId);
                //x.OrderStatus = GetInstanceType(x.InstanceNumber);
                if (x.IsProvideColor == true)
                {
                    x.ColorType = "提供实物颜色参考样";
                }
                else if (x.IsAccordingActualResult == true)
                {
                    x.ColorType = "按数码稿";
                }
                else if (x.IsAccordingDigitalDraft == true)
                {
                    x.ColorType = "根据实际打样结果";
                }
                switch (x.Division)
                {
                    case "1":
                        x.Division = "DIY";
                        break;
                    case "2":
                        x.Division = "工程";
                        break;
                    case "3":
                        x.Division = "厨卫";
                        break;
                    case "4":
                        x.Division = "臻辅材";
                        break;
                    case "5":
                        x.Division = "秀珀";
                        break;
                    case "6":
                        x.Division = "长润发";
                        break;
                    case "7":
                        x.Division = "AR";
                        break;
                    case "8":
                        x.Division = "雅士利";
                        break;
                    case "9":
                        x.Division = "SAF";
                        break;
                    default:
                        x.Division = "";
                        break;
                }
                switch (x.LayoutChangeType)
                {
                    case "1":
                        x.LayoutChangeType = "仅文字变更";
                        break;
                    case "2":
                        x.LayoutChangeType = "色彩或图案变更";
                        break;
                    case "3":
                        x.LayoutChangeType = "全新版面";
                        break;
                    case "4":
                        x.LayoutChangeType = "其他";
                        break;
                    case "5":
                        x.LayoutChangeType = "包材供应商协助修改版面";
                        break;
                    default:
                        x.LayoutChangeType = "";
                        break;
                }
            });
            //返回结果
            return new PagedResultDto<GetBZWGYSDYOutput>()
            {
                TotalCount = totalCount,
                Items = listViewDto
            };
        }

        public async Task<List<GetBZWGYSDYOutput>> ExportAsync(BZWGYSDYInput input)
        {
            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToListAsync();
            listViewDto.ForEach(x => {
               // x.OrderStatus = GetInstanceType(x.InstanceNumber);
                if (x.IsProvideColor == true)
                {
                    x.ColorType = "提供实物颜色参考样";
                }
                else if (x.IsAccordingActualResult == true)
                {
                    x.ColorType = "按数码稿";
                }
                else if (x.IsAccordingDigitalDraft == true)
                {
                    x.ColorType = "根据实际打样结果";
                }
                switch (x.Division)
                {
                    case "1":
                        x.Division = "DIY";
                        break;
                    case "2":
                        x.Division = "工程";
                        break;
                    case "3":
                        x.Division = "厨卫";
                        break;
                    case "4":
                        x.Division = "臻辅材";
                        break;
                    case "5":
                        x.Division = "秀珀";
                        break;
                    case "6":
                        x.Division = "长润发";
                        break;
                    case "7":
                        x.Division = "AR";
                        break;
                    case "8":
                        x.Division = "雅士利";
                        break;
                    case "9":
                        x.Division = "SAF";
                        break;
                    default:
                        x.Division = "";
                        break;
                }
                switch (x.LayoutChangeType)
                {
                    case "1":
                        x.LayoutChangeType = "仅文字变更";
                        break;
                    case "2":
                        x.LayoutChangeType = "色彩或图案变更";
                        break;
                    case "3":
                        x.LayoutChangeType = "全新版面";
                        break;
                    case "4":
                        x.LayoutChangeType = "其他";
                        break;
                    case "5":
                        x.LayoutChangeType = "包材供应商协助修改版面";
                        break;
                    default:
                        x.LayoutChangeType = "";
                        break;
                }
            });
            return listViewDto;
        }

        /// <summary>
        /// 获取Queryable(报表展现)
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        private ISugarQueryable<GetBZWGYSDYOutput> GetQueryable(BZWGYSDYInput input)
        {
            var listQueryable = _db.Queryable<BZWGYSDYHeader, BZWGYSDYDetails, BusinessProcessesNew>(
                    (x, m, bu) => new JoinQueryInfos(JoinType.Left, x.Id == m.ParentId, JoinType.Left, x.InstanceNumber == bu.InstanceId))
                .WhereIF(!string.IsNullOrWhiteSpace(input.InstanceNumber), (x, m) => x.InstanceNumber.Contains(input.InstanceNumber))
                .WhereIF(!string.IsNullOrWhiteSpace(input.Division), (x, m) => x.Division.Contains(input.Division))
                .WhereIF(!string.IsNullOrWhiteSpace(input.MaterialCode), (x, m) => m.MaterialCode.Contains(input.MaterialCode))
                .WhereIF(!string.IsNullOrWhiteSpace(input.MaterialName), (x, m) => m.MaterialName.Contains(input.MaterialName))
                .WhereIF(!string.IsNullOrWhiteSpace(input.OldMaterialCode), (x, m) => m.OldMaterialCode.Contains(input.OldMaterialCode))
                .WhereIF(!string.IsNullOrWhiteSpace(input.OldMaterialName), (x, m) => m.OldMaterialName.Contains(input.OldMaterialName))
                .WhereIF(!input.OrderStatus.IsNullOrEmpty(), (x, m, bu) => SqlFunc.ContainsArray<string>(input.OrderStatus.ToArray(), bu.ProcessStatusName))
                .WhereIF(!string.IsNullOrWhiteSpace(input.AddUserName), (x, m, bu) => bu.StartUserName.Equals(input.AddUserName))
                .WhereIF(input.StartCreationTime != null && input.EndCreationTime != null, x => x.CreateTime >= input.StartCreationTime && x.CreateTime.AddDays(-1) <= input.EndCreationTime)
                .Select((x, m, bu) =>
                    new GetBZWGYSDYOutput()
                    {
                        InstanceNumber = x.InstanceNumber,
                        CreateTime = x.CreateTime,
                        AddUserName = bu.StartUserName,
                        OrderStatus=bu.ProcessStatusName,
                        FinishTime = bu.FinishTime,
                        Division = x.Division,
                        LayoutChangeType = x.LayoutChangeType,
                        LayoutChangeDesc = x.LayoutChangeDesc,
                        IsProvideColor = x.IsProvideColor,
                        IsAccordingActualResult = x.IsAccordingActualResult,
                        IsAccordingDigitalDraft = x.IsAccordingDigitalDraft,
                        IsSealed = x.IsSealed,
                        MaterialCode = m.MaterialCode,
                        MaterialName = m.MaterialName,
                        OldMaterialCode = m.OldMaterialCode,
                        OldMaterialName = m.OldMaterialName,
                        MaterialVersion = m.MaterialVersion
                    }).MergeTable().Distinct().OrderBy(ins => ins.InstanceNumber, OrderByType.Desc);
            return listQueryable;
        }
        #endregion

        private string GetInstanceType(string instanceId)
        {
            var state = string.Empty;
            var query = _dbEngine
                .Queryable<Instances, InstanceStates>((it, its) => it.InstanceId == its.InstanceId)
                .WhereIF(!string.IsNullOrEmpty(instanceId), (it, its) => it.Number == instanceId)
                .Select((it, its) => new
                {
                    state = its
                }).ToList();

            if (query.Any())
            {
                var s = query.First().state.Status;
                state = ConvertToQueryStatus((TaskCommonStatus)s);
            }

            return state;
        }

        private string ConvertToQueryStatus(TaskCommonStatus status, bool isInnerState = false)
        {
            string queryStatus;

            switch (status)
            {
                case TaskCommonStatus.RecallStart:
                    queryStatus = "待发起";
                    break;
                case TaskCommonStatus.Start:
                case TaskCommonStatus.ReStart:
                    queryStatus = "发起";
                    break;
                case TaskCommonStatus.Processing:
                    queryStatus = "处理中";
                    break;
                case TaskCommonStatus.RejectActivity:
                case TaskCommonStatus.RejectActivityDirect:
                case TaskCommonStatus.Handover:
                case TaskCommonStatus.ExtraAppend:
                case TaskCommonStatus.ExtraInsert:
                case TaskCommonStatus.SkippedWhenEmptyResolver:
                case TaskCommonStatus.SkippedWhenSameApprover:
                    queryStatus = isInnerState ? "已完成" : "处理中";
                    break;
                case TaskCommonStatus.Done:
                    queryStatus = "通过";
                    break;
                case TaskCommonStatus.Refused:
                    queryStatus = "拒绝";
                    break;
                case TaskCommonStatus.Canceled:
                case TaskCommonStatus.InterveneAddNode:
                case TaskCommonStatus.InterveneJumpNode:
                case TaskCommonStatus.InterveneChangeUsers:
                case TaskCommonStatus.InterveneReorder:
                case TaskCommonStatus.InterveneRemoveNode:
                    queryStatus = "终止";
                    break;
                case TaskCommonStatus.RejectStart:
                case TaskCommonStatus.RejectStartDirect:
                    queryStatus = "退回";
                    break;
                case TaskCommonStatus.Exception:
                    queryStatus = "有异常";
                    break;
                case TaskCommonStatus.RecallActivity:
                    queryStatus = "撤回";
                    break;
                default:
                    queryStatus = "待发起";
                    break;
            }

            return queryStatus;
        }

    }
}